package com.cy.store.controller;

import com.cy.store.controller.ex.*;
import com.cy.store.entity.User;
import com.cy.store.service.IUserService;
import com.cy.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

//拦截users请求
@RestController
@RequestMapping("users")
public class UserController extends BaseController{
    @Autowired
    private IUserService userService;

    //pojo
    @RequestMapping("reg")
    public JsonResult<Void> reg(User user){
        userService.reg(user);
        return new JsonResult<>(OK);
    }

    //非pojo
    @RequestMapping("login")
    public  JsonResult<User> login(String username, String password, HttpSession session){
        User user = userService.login(username, password);
        //想session对象中注入数据
        session.setAttribute("uid", user.getUid());
        session.setAttribute("username", user.getUsername());

        //System.out.println(session.getAttribute("uid"));
        //System.out.println(session.getAttribute("username"));

        return new JsonResult<User>(OK, user);
    }

    //密码修改
    @RequestMapping("change_password")
    public JsonResult<Void> changePassword(String oldPassword, String newPassword, HttpSession session){
        userService.changePassword(getUidFromSession(session),oldPassword,newPassword);
        return new JsonResult<Void>(OK);
    }

    //个人资料获取
    @RequestMapping("get_by_uid")
    public JsonResult<User> getByUid(HttpSession session){
        User user = userService.getById(getUidFromSession(session));
        return new JsonResult<User>(OK, user);
    }

    //个人资料修改
    @RequestMapping("change_info")
    public JsonResult<Void> changeInfo(User user, HttpSession session){
        userService.changeInfo(getUidFromSession(session), user);
        return new JsonResult<Void>(OK);
    }


    //头像上传
    //参数名不能出错，因为前端按照属性名去分配值的；参数类型也不能变，前端会传输对应类型数据
    /*
    * 如果参数名和前端页面的控件名不同，
    * 也可在参数前加上注解@RequestParam(value = "参数名", required=true/false)
    * 可以定向将请求中的某个参数注入到处理方法的参数上，即进行标记和映射
    * */
    /*MultipartFile是SpringMVC提供的一个接口，其封装了接受文件的方法（可接受任何类型的file），
    * 经过SpringBoot的整合，只需要在请求处理方法的参数列表上声明一个MultipartFile类型参数，
    * SpringBoot就会自动将文件数据传递到这个参数上
    * */
    @RequestMapping("change_avatar")
    public JsonResult<String> changeAvatar(HttpSession session, @RequestParam("file") MultipartFile file){
        //判断文件是否为空，FileEmptyExcaption异常
        if(file.isEmpty()) throw new FileEmptyExcaption("文件为空");

        //判断文件大小，FileSizeException异常
        if(file.getSize()>AVATAR_MAX_SIZE) throw new FileSizeException("不允许上传超出" + (AVATAR_MAX_SIZE/1024) + "KB大小的头像");

        //判断文件类型，FileTypeException异常
        if(!AVATAR_TYPE.contains(file.getContentType())) throw new FileTypeException("不支持当前格式文件上传，仅允许的文件类型为：\n" + AVATAR_TYPE);


        /*寻找upload文件夹在磁盘的位置，无则在默认位置直接创建个upload文件
        然后根据上传文件的类型，随机出一个同类型的文件名
        根据上述的位置和文件名新建一个文件，然后将上传过来的文件写入新文件中，异常处理*/

        //获取upload文件夹在磁盘的真是位置(虽然目前upload文件夹还不存在)
        //设定文件路径并检验是否存在，无则创建文件
        String parent = session.getServletContext().getRealPath("upload");
        System.out.println("文件路径在：" + parent);
        File dir = new File(parent);
        if(!dir.exists()) dir.mkdirs();
        //保存头像文件的文件名
        String suffix = "";
        String originalFilename = file.getOriginalFilename();         //获取带后缀的文件名
        int beginIndex = originalFilename.lastIndexOf(".");     //返回.在String中最后一次索引
        if(beginIndex > 0) suffix = originalFilename.substring(beginIndex);    //得到文件类型
        String filename = UUID.randomUUID().toString() + suffix;        //随机生成表示名+类型作为上传文件的名字

        File dest = new File(dir, filename);             //指定路径下创建指定文件
        try {
            file.transferTo(dest);                       //将file中信息写入dest文件中
        } catch (IOException e) {
            throw new FileUploadIOException("上传文件时读写错误，请稍后重尝试");
        } catch (IllegalStateException e){
            throw new FileStateException("文件状态异常，可能文件已被移动或删除");
        }

        //头像路径
        String avater = "/upload/" + filename;
        //写入数据库
        userService.changeAvatar(getUidFromSession(session), avater);

        return new JsonResult<String>(OK, avater);
    }

    //上传的文件的最大值
    public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;

    //限制上传文件的类型
    public static final List<String> AVATAR_TYPE = new ArrayList<>();
    static {
        AVATAR_TYPE.add("image/jepg");
        AVATAR_TYPE.add("image/png");
        AVATAR_TYPE.add("image/bmp");
        AVATAR_TYPE.add("image/gif");
    }


}
